﻿using Dao;
using Infrastructure.MyException;
using ShareCode.Entity;
using ShareCode.KeyValue;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Bll
{
    public interface IRepairBll<T> : IBaseBll<T> where T : BaseBaseEntity, IRepairEntity, new()
    {

        public async Task<T> UpdateOrInsertForRepairAsync(T model, bool verify = true)
        {
            if (model.Id == 0)
            {
                await GetDao()!.InsertAsync(model);

                return model;
            }

            var oldEndity = await GetDao()!.FirstAsync(t => t.Id == model.Id);

            if (oldEndity == default)
            {
                throw new ShowUserLogicException("没有找到更新目标").AddSonMessage(nameof(model.Id), "没有找到更新目标");
            }

            if (oldEndity.VersionId != model.VersionId)
            {
                //如果版本ID相同，直接修改就可以了
                model.RepairTargetId = model.Id;
                model.Id = 0;
                model.RepairMethod = (int)EnumRepairMethod.Update;

                var b = await GetDao()!.InsertAsync(model);

                return model;

            }

            var a = await GetDao()!.UpdateAsync(model);

            return model;
        }


        public async Task<bool> DeleteByIdAsync(long ids, long currentVersionId)
        {
            return await DeleteByIdAsync([ids], currentVersionId);
        }
        public async Task<bool> DeleteByIdAsync(List<long> Ids, long currentVersionId)
        {
            var models = await GetDao()!.GetListAsync(t => Ids.Contains(t.Id));

            List<T> AddModel = [];
            List<long> UpdateIds = [];

            foreach (var a in models)
            {
                if (a.VersionId != currentVersionId)
                {
                    a.RepairMethod = (int)EnumRepairMethod.Delete;
                    a.RepairTargetId = a.Id;
                    a.Id = 0;
                    a.VersionId = currentVersionId;
                    AddModel.Add(a);
                    continue;
                }

                UpdateIds.Add(a.Id);
            }

            if (AddModel.Count > 0)
            {
                await GetDao()!.InsertRangeAsync(AddModel);
            }

            if (UpdateIds.Count > 0)
            {
                await GetDao()!.AsDeleteable().Where(t => UpdateIds.Contains(t.Id)).ExecuteCommandAsync();
            }

            return true;
        }


        public async Task<bool> LogicDeleteByIdAsync(long ids, long currentVersionId)
        {
            return await LogicDeleteByIdAsync([ids], currentVersionId);
        }
        public async Task<bool> LogicDeleteByIdAsync(List<long> Ids, long currentVersionId)
        {
            var models = await GetDao()!.GetListAsync(t => Ids.Contains(t.Id));

            List<T> AddModel = [];
            List<long> UpdateIds = [];

            foreach (var a in models)
            {
                if (a.VersionId != currentVersionId)
                {
                    a.RepairMethod = (int)EnumRepairMethod.Update;
                    a.RepairTargetId = a.Id;
                    a.Id = 0;
                    a.VersionId = currentVersionId;
                    a.IsDelete = 1;
                    AddModel.Add(a);
                    continue;
                }

                UpdateIds.Add(a.Id);
            }

            if (AddModel.Count > 0)
            {
                await GetDao()!.InsertRangeAsync(AddModel);
            }

            return await GetDao()!.LogicDeleteByIdAsync(UpdateIds);
        }


        public async Task<bool> UnLogicDeleteByIdAsync(long ids, long currentVersionId)
        {
            return await UnLogicDeleteByIdAsync([ids], currentVersionId);
        }
        public async Task<bool> UnLogicDeleteByIdAsync(List<long> Ids, long currentVersionId)
        {
            var models = await GetDao()!.GetListAsync(t => Ids.Contains(t.Id));

            List<T> AddModel = [];
            List<long> UpdateIds = [];

            foreach (var a in models)
            {
                if (a.VersionId != currentVersionId)
                {
                    a.RepairMethod = (int)EnumRepairMethod.Update;
                    a.RepairTargetId = a.Id;
                    a.Id = 0;
                    a.VersionId = currentVersionId;
                    a.IsDelete = 0;
                    AddModel.Add(a);
                    continue;
                }

                UpdateIds.Add(a.Id);
            }

            if (AddModel.Count > 0)
            {
                await GetDao()!.InsertRangeAsync(AddModel);
            }

            return await GetDao()!.UnLogicDeleteByIdAsync(Ids);
        }


    }
}
